﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Bierdopje.API
{
    /// <summary>
    /// This is a generic XML helper class
    /// </summary>
    public class XMLHelper
    {
        /// <summary>
        /// Remove all HTML entities from a textual representation of an xml document so
        /// it can be parsed. (HTML entities will give an error)
        /// </summary>
        /// <param name="rawXml">XML to cleanup</param>
        /// <returns>A string containing XML without HTML entities</returns>
        public static string XMLCleanup(string rawXml)
        {
            string[] xmlEntities = new string[] { @"&#34;", @"&#38;", @"&#38;", @"&#60;", @"&#62;", @"&#160;", @"&#161;", @"&#162;", @"&#163;", @"&#164;", @"&#165;", @"&#166;", @"&#167;", @"&#168;", @"&#169;", @"&#170;", @"&#171;", @"&#172;", @"&#173;", @"&#174;", @"&#175;", @"&#176;", @"&#177;", @"&#178;", @"&#179;", @"&#180;", @"&#181;", @"&#182;", @"&#183;", @"&#184;", @"&#185;", @"&#186;", @"&#187;", @"&#188;", @"&#189;", @"&#190;", @"&#191;", @"&#192;", @"&#193;", @"&#194;", @"&#195;", @"&#196;", @"&#197;", @"&#198;", @"&#199;", @"&#200;", @"&#201;", @"&#202;", @"&#203;", @"&#204;", @"&#205;", @"&#206;", @"&#207;", @"&#208;", @"&#209;", @"&#210;", @"&#211;", @"&#212;", @"&#213;", @"&#214;", @"&#215;", @"&#216;", @"&#217;", @"&#218;", @"&#219;", @"&#220;", @"&#221;", @"&#222;", @"&#223;", @"&#224;", @"&#225;", @"&#226;", @"&#227;", @"&#228;", @"&#229;", @"&#230;", @"&#231;", @"&#232;", @"&#233;", @"&#234;", @"&#235;", @"&#236;", @"&#237;", @"&#238;", @"&#239;", @"&#240;", @"&#241;", @"&#242;", @"&#243;", @"&#244;", @"&#245;", @"&#246;", @"&#247;", @"&#248;", @"&#249;", @"&#250;", @"&#251;", @"&#252;", @"&#253;", @"&#254;", @"&#255;" };
            string[] htmlEntities = new string[] { @"&quot;", @"&amp;", @"&amp;", @"&lt;", @"&gt;", @"&nbsp;", @"&iexcl;", @"&cent;", @"&pound;", @"&curren;", @"&yen;", @"&brvbar;", @"&sect;", @"&uml;", @"&copy;", @"&ordf;", @"&laquo;", @"&not;", @"&shy;", @"&reg;", @"&macr;", @"&deg;", @"&plusmn;", @"&sup2;", @"&sup3;", @"&acute;", @"&micro;", @"&para;", @"&middot;", @"&cedil;", @"&sup1;", @"&ordm;", @"&raquo;", @"&frac14;", @"&frac12;", @"&frac34;", @"&iquest;", @"&Agrave;", @"&Aacute;", @"&Acirc;", @"&Atilde;", @"&Auml;", @"&Aring;", @"&AElig;", @"&Ccedil;", @"&Egrave;", @"&Eacute;", @"&Ecirc;", @"&Euml;", @"&Igrave;", @"&Iacute;", @"&Icirc;", @"&Iuml;", @"&ETH;", @"&Ntilde;", @"&Ograve;", @"&Oacute;", @"&Ocirc;", @"&Otilde;", @"&Ouml;", @"&times;", @"&Oslash;", @"&Ugrave;", @"&Uacute;", @"&Ucirc;", @"&Uuml;", @"&Yacute;", @"&THORN;", @"&szlig;", @"&agrave;", @"&aacute;", @"&acirc;", @"&atilde;", @"&auml;", @"&aring;", @"&aelig;", @"&ccedil;", @"&egrave;", @"&eacute;", @"&ecirc;", @"&euml;", @"&igrave;", @"&iacute;", @"&icirc;", @"&iuml;", @"&eth;", @"&ntilde;", @"&ograve;", @"&oacute;", @"&ocirc;", @"&otilde;", @"&ouml;", @"&divide;", @"&oslash;", @"&ugrave;", @"&uacute;", @"&ucirc;", @"&uuml;", @"&yacute;", @"&thorn;", @"&yuml;" };

            if (htmlEntities.Length == xmlEntities.Length)
            {
                for (int i = 0; i < htmlEntities.Length; i++)
                {
                    rawXml = rawXml.Replace(htmlEntities[i], xmlEntities[i]);
                }
            }

            rawXml = rawXml.Replace(" & ", " &amp; ");
            return rawXml.Replace("-&-", " &amp; ");
        }

        /// <summary>
        /// Extract and covert text from a child of a xmlnode
        /// </summary>
        /// <param name="xmlNode">The node to convert</param>
        /// <param name="field">The field to retrieve</param>
        /// <returns>Clean data, if conversion fails a default is returned</returns>
        public static DateTime ExtractDateTimeFromNode(XmlNode xmlNode, string field)
        {
            try
            {
                return Convert.ToDateTime(xmlNode.SelectSingleNode(field).InnerText);
            }
            catch (Exception)
            {
                return DateTime.MinValue;
            }
        }

        /// <summary>
        /// Extract and covert text from a child of a xmlnode
        /// </summary>
        /// <param name="xmlNode">The node to convert</param>
        /// <param name="field">The field to retrieve</param>
        /// <returns>Clean data, if conversion fails a default is returned</returns>
        public static string ExtractStringFromNode(XmlNode xmlNode, string field)
        {
            try
            {
                return xmlNode.SelectSingleNode(field).InnerText;
            }
            catch (Exception)
            {
                return "";
            }
        }

        /// <summary>
        /// Extract and covert text from a child of a xmlnode
        /// </summary>
        /// <param name="xmlNode">The node to convert</param>
        /// <param name="field">The field to retrieve</param>
        /// <returns>Clean data, if conversion fails a default is returned</returns>
        public static Int32 ExtractIntFromNode(XmlNode xmlNode, string field)
        {
            try
            {
                return Convert.ToInt32(xmlNode.SelectSingleNode(field).InnerText);
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// Extract and covert text from a child of a xmlnode
        /// </summary>
        /// <param name="xmlNode">The node to convert</param>
        /// <param name="field">The field to retrieve</param>
        /// <returns>Clean data, if conversion fails a default is returned</returns>
        public static Decimal ExtractDecimalFromNode(XmlNode xmlNode, string field)
        {
            try
            {
                return Convert.ToDecimal(xmlNode.SelectSingleNode(field).InnerText);
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// Extract and covert text from a child of a xmlnode
        /// </summary>
        /// <param name="xmlNode">The node to convert</param>
        /// <param name="field">The field to retrieve</param>
        /// <returns>Clean data, if conversion fails a default is returned</returns>
        public static bool ExtractBoolFromNode(XmlNode xmlNode, string field)
        {
            try
            {
                return bool.Parse(xmlNode.SelectSingleNode(field).InnerText);
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
